#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>

#include <vector>
using namespace std;

int g_recvfd;
vector<int> g_fdArry;		//connection fd array

int socket_noblock(const int fd)
{
	long fd_opts = fcntl(fd, F_GETFL);
	if (-1 == fd_opts)
	{
		perror("fcntl:F_GETFL");
		return -1;
	}

	fd_opts |= O_NONBLOCK;
	if (-1 == fcntl(fd, F_SETFL, fd_opts))
	{
		perror("fcntl:F_SETFL");
		return -1;
	}

	return 0;
};

int recvfd(int fd, void *ptr, int nbytes, int *rstfd)
{
	struct msghdr msg;
	struct iovec iov[1];
	ssize_t n;

	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	
	iov[0].iov_base = ptr;
	iov[0].iov_len = nbytes;
	msg.msg_iov = iov;
	msg.msg_iovlen = 1;

	union
	{
		struct cmsghdr cm;
		char control[CMSG_SPACE(sizeof(int))];
	}control_un;
	struct cmsghdr *cmptr;
	
	msg.msg_control = control_un.control;
	msg.msg_controllen = sizeof(control_un.control);

	if(( recvmsg(fd, &msg, 0)) < 0)
	{
		//perror("recv fd");
		//printf("errno %d, %s", errno, strerror(errno));
		return -1;
	}

	if( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
		cmptr->cmsg_len == CMSG_LEN(sizeof(int)))
	{
		*rstfd = *((int *)CMSG_DATA(cmptr));
	}
	else
	{
		*rstfd = -1;
		perror("111");
	}
	return (n);

};

int register1()
{
	char szLocal[]="/tmp/unix_local";
	g_recvfd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if(g_recvfd == -1)
	{
		perror("local socket");
		return -1;
	}

	struct sockaddr_un addr;
	addr.sun_family = AF_LOCAL;
	strcpy(addr.sun_path, szLocal);

	int nrst =	connect(g_recvfd, (struct sockaddr *)&addr, sizeof(addr));
	if( nrst == -1)
	{
		perror("local connect");
		return -1;
	}
	socket_noblock(g_recvfd);

	return 0;
};


int main(int args, char **argv)
{
	int nrst = register1();
	if(nrst == -1)
	{
		return -1;
	}

	char szBuf[12], szRecv[1024], szSend[1024];
	for(; ;)
	{
		int connfd = -1;
		recvfd(g_recvfd,(void *)szBuf,12,&connfd);
		
		if(connfd != -1)
		{
			socket_noblock(connfd);
			g_fdArry.push_back(connfd);
		}

		vector<int>::iterator iter = g_fdArry.begin();
		for(; iter != g_fdArry.end(); ++iter)
		{
			memset(szRecv, 0, 1024);
			recv(*iter, szRecv, 1024, 0);
			printf("recv a msg : %s\n", szRecv);
			memcpy(szSend, szRecv, strlen(szRecv) + 1);
			send(*iter, szSend, strlen(szSend), 0);
		}
	}

	return 0;
}


